﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Windows.Forms;
using InkFx.WinControl.Core;
using DA = Temp_20190707_AForm.DockAlignment;
using DTGS = Temp_20190707_AForm.DockTabGroupState;

namespace Temp_20190707_AForm
{
    public partial class DockFloatForm : System.Windows.Forms.Form
    {
        public DockFloatForm()
        {
            InitializeComponent();
            base.Padding = new Padding(PADDING);
            //base.DoubleBuffered = true; //这种需要快速弹出的窗体, 设置 双缓冲 只会减慢启动速度
            this.ShowInTaskbar = false;
        }

        public static DockFloatForm ShowControl(DockPanel dockPanel, DockTabGroup group, Rectangle rect)
        {
            DockPopPanel.TogglePopGroup(null);

            DockFloatForm form = new DockFloatForm();
            form.TabGroup = group;
            form.DockPanel = dockPanel;

            if (rect != Rectangle.Empty)
            {
                form.StartPosition = FormStartPosition.Manual;
                form.Bounds = rect;
            }

            group.Dock = DockStyle.Fill;
            group.State = DTGS.Float;
            group.Parent = form;
            form.Show(dockPanel.FindForm());
            group.Focus();

            //dockPanel.DoLayout();
            dockPanel.Invalidate();
            return form;
        }

        public const int PADDING = 3;
        public DockTabGroup TabGroup { get; private set; }
        public DockPanel DockPanel { get; private set; }


        private List<DockFloatTipForm> m_ListTipForm = new List<DockFloatTipForm>();
        public void ShowDLPanel()
        {
            var dockPanel = DockPanel;
            if (dockPanel == null || dockPanel.Disposing || dockPanel.IsDisposed) return;

            var list1 = new List<Control>();
            var list2 = new List<Control>();
            list1.Add(dockPanel);
            if (dockPanel.CenterPanel != null) list1.Add(dockPanel.CenterPanel);
            if (dockPanel.ListTabGroup != null)
            {
                var curr = this.TabGroup;
                var list4 = new List<DockTabGroup>(dockPanel.ListTabGroup);
                foreach (var group in list4)
                {
                    if (group == curr || !ShowDockTipForm(group)) continue;
                    list1.Add(group);
                }
            }

            var point = Control.MousePosition;
            foreach (var ctrl in list1)
            {
                var rect = Win32API.GetWindowRectangle(ctrl.Handle);
                if (rect.Contains(point)) { list2.Add(ctrl); }
            }

            var list3 = new List<DockFloatTipForm>(m_ListTipForm);
            foreach (var ctrl in list2)
            {
                var temp = ctrl;
                DockFloatTipForm form = m_ListTipForm.Find(x => x.Control == temp);
                if (form != null) { list3.Remove(form); form.Invalidate(); }
                else
                {
                    form = DockFloatTipForm.ShowDLPanel(dockPanel, ctrl, this);
                    if (form != null) m_ListTipForm.Add(form);
                }
            }

            foreach (var form in list3)
            {
                form.Dispose();
                m_ListTipForm.Remove(form);
            }
        }
        public void HideDLPanel()
        {
            if (m_ListTipForm != null)
            {
                foreach (var form2 in m_ListTipForm) { form2.Dispose(); }
                m_ListTipForm.Clear();
            }
        }



        private bool ShowDockTipForm(DockTabGroup group)
        {
            if (group == null) return false;
            bool hide = !group.Visible || (group == this.TabGroup) || (group.State != DTGS.Expand && group.State != DTGS.Float && group.State != DTGS.Popup);
            if (hide) return false;

            //var handle = this.Handle;
            //var rect = Win32API.GetWindowRectangle(handle);
            //if (handle != Win32API.WindowFromPoint(new Point(rect.X + 1, rect.Y + 1))) return false;
            //if (handle != Win32API.WindowFromPoint(new Point(rect.X + rect.Width - 1, rect.Y + 1))) return false;
            //if (handle != Win32API.WindowFromPoint(new Point(rect.X + 1, rect.Y + rect.Height - 1))) return false;
            //if (handle != Win32API.WindowFromPoint(new Point(rect.X + rect.Width - 1, rect.Y + rect.Height - 1))) return false;
            
            return true;
        }
        public DockEventArgs NewDockEventArgs()
        {
            if (m_ListTipForm == null || m_ListTipForm.Count <= 0) return null;

            foreach (var form in m_ListTipForm)
            {
                var e = form.NewDockEventArgs();
                if (e != null) { return e; }
            }
            return null;
        }

        protected override void OnShown(EventArgs e)
        {
            base.OnShown(e);
            base.DoubleBuffered = true;
        }
        protected override void OnLocationChanged(EventArgs e)
        {
            base.OnLocationChanged(e);

            if (MouseButtons == MouseButtons.Left) this.ShowDLPanel();
        }
        protected override void OnControlRemoved(ControlEventArgs e)
        {
            base.OnControlRemoved(e);

            DockTabGroup group = null;
            foreach (var ctrl in this.Controls)
                if (ctrl is DockTabGroup) { group = (DockTabGroup)ctrl; break; }

            if (group != null) { this.TabGroup = group; }
            else { Dispose(); }
        }
        public new void Dispose()
        {
            HideDLPanel();

            var group = this.TabGroup;
            var form = group == null ? null : group.FindForm();
            if (form == this) group.Parent = null;

            TabGroup = null;
            DockPanel = null;
            if (!this.Disposing && !this.IsDisposed) { this.Close(); base.Dispose(); }
        }
    }
}
